package com.huashi.dealer.modular.business.message.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huashi.dealer.commonEntity.*;
import com.huashi.dealer.core.exception.ServiceException;
import com.huashi.dealer.core.page.PageFactory;
import com.huashi.dealer.core.util.BizAssertUtil;
import com.huashi.dealer.core.util.SaTokenUtil;
import com.huashi.dealer.modular.business.goods.mapper.GoodsImageMapper;
import com.huashi.dealer.modular.business.goods.mapper.GoodsSkuMapper;
import com.huashi.dealer.modular.business.goods.service.GoodsService;
import com.huashi.dealer.modular.business.message.mapper.MessageCategoryMapper;
import com.huashi.dealer.modular.business.message.mapper.MessageMapper;
import com.huashi.dealer.modular.business.message.param.StoreMessageListParam;
import com.huashi.dealer.modular.business.message.service.MessageService;
import com.huashi.dealer.modular.business.message.param.MessageResponseParam;
import com.huashi.dealer.modular.business.message.vo.HotGoodsVo;
import com.huashi.dealer.modular.business.message.vo.IndexPageVo;
import com.huashi.dealer.modular.business.message.vo.NewGoodsVo;
import com.huashi.dealer.modular.business.upload.service.UploadService;
import com.huashi.dealer.modular.business.user.service.UserService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.concurrent.Executor;

/**
 * API消息服务实现类
 *
 * @author 谭陈强
 * @since 2025-07-30
 */
@Service("apiMessageServiceImpl")
@Slf4j
public class MessageServiceImpl extends ServiceImpl<MessageMapper, Message> implements MessageService {
    @Resource
    private MessageCategoryMapper messageCategoryMapper;
    @Resource
    private UploadService uploadService;
    @Autowired
    private GoodsService goodsService;
    @Autowired
    private GoodsImageMapper goodsImageMapper;
    @Autowired
    private GoodsSkuMapper goodsSkuMapper;
    @Autowired
    private Executor asyncServiceExecutor ;
    @Autowired
    private UserService userService;

    @Override
    public List<MessageCategory> getMessageIndex(String type) {
        LambdaQueryWrapper<MessageCategory> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MessageCategory::getIsType, type);
        queryWrapper.orderByAsc(MessageCategory::getSort);
        return messageCategoryMapper.selectList(queryWrapper);
    }

    @Override
    public Page<MessageResponseParam> getMessageList(Message message, Page<Message> page) {
        Long id = SaTokenUtil.getLoginId();
        Page<MessageResponseParam> responseParam = new Page<>();
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(message.getIsType() != null && message.getIsType() != 0, Message::getIsType, message.getIsType());
//        queryWrapper.eq(message.getCategoryId()!= null && message.getCategoryId() != 0, Message::getCategoryId, message.getCategoryId());
//        if(30 == message.getIsType() ) {
            //todo 正式环境放开
            queryWrapper.eq(Message::getUserId, id);
//        }
        queryWrapper.in(ObjectUtil.isNotEmpty(message.getIsType()) && message.getIsType() != 0, Message::getIsType, message.getIsType());
        queryWrapper.eq(ObjectUtil.isNotEmpty(message.getCategoryId()) && message.getCategoryId() != 0, Message::getCategoryId, message.getCategoryId());
//        if (ObjectUtil.isNotEmpty(message.getIsType()) && message.getIsType() == 30) {
//            queryWrapper.eq(Message::getUserId, id);
//        }
       if(message.getIsType() == 10 || message.getIsType() == 20){
           queryWrapper.orderByAsc(Message::getMessageSort);
       }
        queryWrapper.orderByDesc(Message::getCreateTime);
        Page<Message> messagePage = this.baseMapper.selectPage(page, queryWrapper);
        List<Message> messageList = messagePage.getRecords();
        BeanUtils.copyProperties(messagePage, responseParam);
        if (messageList.isEmpty()){
            return responseParam;
        }
        List<MessageResponseParam> list = messageList.stream().map(messages -> {
            MessageResponseParam responseParamBo = new MessageResponseParam();
            responseParamBo.setMessage(messages);
            if(messages.getImageId() != null &&  messages.getImageId() != 0 && messages.getImageId() != 0L) {
                responseParamBo.setImage(uploadService.getById(messages.getImageId()));
            }
            if(messages.getPdfId() != null &&  messages.getPdfId() != 0 && messages.getPdfId() != 0L) {
                responseParamBo.setPdf(uploadService.getById(messages.getPdfId()));
            }
            responseParamBo.setCategory(messageCategoryMapper.selectById(messages.getCategoryId()));
            return responseParamBo;
        }).toList();
        responseParam.setRecords(list);
        return responseParam;
    }

    @Override
    public MessageResponseParam getMessageDetail(Long messageId) {
        MessageResponseParam responseParam = new MessageResponseParam();
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Message::getMessageId, messageId);
        Message message = this.baseMapper.selectOne(queryWrapper);
        Optional.ofNullable(message).orElseThrow(() -> new ServiceException("消息不存在"));
        Optional.ofNullable(message).ifPresent(messages -> {
            responseParam.setMessage(messages);
            if(messages.getImageId() != null &&  messages.getImageId() != 0 && messages.getImageId() != 0L) {
                responseParam.setImage(uploadService.getById(messages.getImageId()));
            }
            if(messages.getPdfId() != null &&  messages.getPdfId() != 0 && messages.getPdfId() != 0L) {
                responseParam.setPdf(uploadService.getById(messages.getPdfId()));
            }
            responseParam.setCategory(messageCategoryMapper.selectById(messages.getCategoryId()));
        });
        LambdaUpdateWrapper<Message> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Message::getMessageId, messageId);
        updateWrapper.set(Message::getActualViews, message.getActualViews() + 1);
        this.baseMapper.update(updateWrapper);
        return responseParam;
    }

    @Override
    public void editMessageStatus(Long messageId) {
        LambdaQueryWrapper<Message> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Message::getMessageId, messageId);
        //todo 正式环境放开
//        queryWrapper.eq(Message::getUserId, SaTokenUtil.getLoginId());
        Message message = this.baseMapper.selectOne(queryWrapper);
        Optional.ofNullable(message).orElseThrow(() -> new ServiceException("消息不存在"));
        message.setStatus(1);
        this.baseMapper.updateById(message);
        if((message.getIsType() == 10 || message.getIsType() == 20) && message.getRelateId()!=null){
            LambdaUpdateWrapper<Message> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.set(Message::getVirtualViews, message.getVirtualViews() + 1);
            updateWrapper.eq(Message::getMessageId,message.getRelateId());
            this.update(updateWrapper);
        }
    }

    @Override
    public void cleanUpMessageStatus() {
        LambdaUpdateWrapper<Message> updateWrapper = new LambdaUpdateWrapper<>();
        Long userId = SaTokenUtil.getLoginId();
        if (userId != null) {
            updateWrapper.eq(Message::getUserId, userId);
            updateWrapper.set(Message::getStatus, 1);
            this.baseMapper.update(updateWrapper);
        }
    }
    @Override
    public Integer calculateMessageStatus(Integer userId) {
        long count = this.count(new LambdaQueryWrapper<Message>().eq(Message::getUserId, userId).eq(Message::getStatus, 0));
        return count > 0 ? 1 : 0;
    }

    @Override
    public void sendMessage(Message  message) {
       this.save( message);
    }

    @Override
    public IndexPageVo getPageIndex() {
        IndexPageVo indexPageVo = new IndexPageVo();
        indexPageVo.setBanner(this.baseMapper.getPageIndex());
        HotGoodsVo hotGoodsVo = new HotGoodsVo();
        NewGoodsVo newGoodsVo = new NewGoodsVo();
        Setting set=this.baseMapper.getSetByKey("store");
        BizAssertUtil.notNull(set, 10001, "未读取到系统相关设置");
        String values = set.getValues();
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> map=new HashMap<>();
        try {
            map = objectMapper.readValue(values, Map.class);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
        String newName = (String)map.get("new_name");
        String hotName = (String)map.get("hot_name");
        LambdaQueryWrapper<Goods > queryWrapper = new LambdaQueryWrapper<Goods>();
        queryWrapper.eq(Goods::getIsDelete, 0)
                .eq(Goods::getIsType, 10)
                .eq(Goods::getGoodsStatus, 10)
                .eq(Goods::getIsNewproduct, 10)
                .orderByAsc(Goods::getGoodsSort)
                .orderByDesc(Goods::getGoodsId)
                .last("LIMIT 100");
        List<Goods> list = goodsService.list(queryWrapper);
        List<Goods> list3 = new ArrayList<>();
        int index1=0;
        for (Goods goods : list){
            if(index1<6) {
                List<GoodsSku> goodsSkus = new ArrayList<>();
                goods.setGoodsImage(goodsImageMapper.getFileUrlByGoodsId(goods.getGoodsId()).get(0));
                GoodsSku goodsSku = goodsSkuMapper.selectOne(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getGoodsId()));
                if(goodsSku == null){
                    continue;
                }
                goodsSkus.add(goodsSku);
                goods.setSku(goodsSkus);
                list3.add(goods);
                index1++;
            }else{
                break;
            }
        }
        newGoodsVo.setGoodsList(list3);
        newGoodsVo.setName(newName);
        indexPageVo.setNewGoods(newGoodsVo);

        LambdaQueryWrapper<Goods> queryWrapper2 = new LambdaQueryWrapper<Goods>();
        queryWrapper2.eq(Goods::getIsDelete, 0)
                .eq(Goods::getIsType, 10)
                .eq(Goods::getGoodsStatus, 10)
                .eq(Goods::getIsHotsellingitem, 10)
                .orderByAsc(Goods::getGoodsSort)
                .orderByDesc(Goods::getGoodsId)
                .last("LIMIT 100");
        List<Goods> list1 = goodsService.list(queryWrapper2);
        List<Goods> list2 = new ArrayList<>();
        int index=0;
        for (Goods goods : list1){
            if (index<6) {
                List<GoodsSku> goodsSkus = new ArrayList<>();
                goods.setGoodsImage(goodsImageMapper.getFileUrlByGoodsId(goods.getGoodsId()).get(0));
                GoodsSku goodsSku = goodsSkuMapper.selectOne(new LambdaQueryWrapper<GoodsSku>().eq(GoodsSku::getGoodsId, goods.getGoodsId()));
                if(goodsSku==null){
                    continue;
                }
                goodsSkus.add(goodsSku);
                goods.setSku(goodsSkus);
                list2.add(goods);
                index++;
            }else {
                break;
            }
        }
        hotGoodsVo.setGoodsList(list2);
        hotGoodsVo.setName(hotName);
        indexPageVo.setHot(hotGoodsVo);
        return indexPageVo;
    }

    @Override
    public Page<Message> getMessageList(StoreMessageListParam param, Page<Message> page) {
        LambdaQueryWrapper<Message> qw = new LambdaQueryWrapper<>();
        qw.orderByAsc(Message::getMessageSort)
                .orderByDesc(Message::getCreateTime);
        if (param.getCategoryId() != null && param.getCategoryId() > 0) {
            qw.eq(Message::getCategoryId, param.getCategoryId());
        }
        if (param.getMessageTitle() != null && !param.getMessageTitle().isEmpty()) {
            qw.like(Message::getMessageTitle, param.getMessageTitle());
        }
        // 支持不同的消息类型，如果没有指定则默认为10（政策通知）

        qw.eq(Message::getIsType, param.getIsType());
        qw.isNull(Message::getRelateId);
        Page<Message> result = this.page(page, qw);
        result.getRecords().forEach(message -> {
            UploadFile file = uploadService.getById(message.getImageId());
            message.setImageUrl(file != null ? file.getFileUrl() : "");
            if(message.getCategoryId() != null && message.getCategoryId() > 0){
                message.setCategoryName(messageCategoryMapper.selectById(message.getCategoryId()).getName());
            }
        });
        return result;
    }

    @Override
    public void saveOrEditMessage(Message param) {
        boolean idAdd=false;
        if (param.getMessageId() == null || param.getMessageId() == 0) {
            param.setCreateTime((System.currentTimeMillis() / 1000));
            param.setUpdateTime((System.currentTimeMillis() / 1000));
            idAdd = true;
        } else {
            param.setUpdateTime(System.currentTimeMillis() / 1000);
        }
        this.saveOrUpdate(param);
        //发消息已通知
        if (idAdd) {
            List<User> list = userService.list();
            asyncServiceExecutor.execute(() -> {
                list.stream().forEach(user -> {
                    Message message = new Message();
                    message.setUserId(user.getUserId().intValue());
                    message.setMessageTitle(param.getMessageTitle());
                    message.setMessageContent(param.getMessageContent());
                    message.setIsType(param.getIsType());
                    message.setStatus(0);
                    message.setPdfId(param.getPdfId());
                    message.setRelateId(param.getMessageId());
                    message.setCategoryId(param.getCategoryId());
                    message.setImageId(param.getImageId());
                    message.setCreateTime(System.currentTimeMillis() / 1000);
                    this.save(message);
                });
            });
        }else{
            param.setStatus(0);
            param.setUpdateTime(System.currentTimeMillis() / 1000);
            LambdaUpdateWrapper<Message> qw = new LambdaUpdateWrapper<>();
            qw.eq(Message::getRelateId, param.getMessageId());
            this.update(param, qw);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteMessage(Long messageId) {
        LambdaUpdateWrapper<Message> qw = new LambdaUpdateWrapper<>();
        qw.eq(Message::getRelateId, messageId)
                .or()
                .eq(Message::getMessageId, messageId);
        this.baseMapper.delete(qw);

    }
} 